import cherrypy
import time
from logst.logs_abstraction import *

class browse:

   def set_max_rows(self, max_rows):

      cherrypy.session['max_rows'] = int(max_rows)
      raise cherrypy.HTTPRedirect('/browse')

   set_max_rows.exposed = True

   def del_daemon_filter(self, daemon_name):

      daemons_hide = cherrypy.session.get('daemons_hide', [])

      if daemons_hide.count(daemon_name):
         daemons_hide.remove(daemon_name)
         cherrypy.session['daemons_hide'] = daemons_hide

         cherrypy.session['last_date'] = None

      raise cherrypy.HTTPRedirect('/browse')

   del_daemon_filter.exposed = True

   def add_daemon_filter(self, daemon_name):

      daemons_hide = cherrypy.session.get('daemons_hide', [])

      if not daemons_hide.count(daemon_name):
         daemons_hide.append(daemon_name)
         cherrypy.session['daemons_hide'] = daemons_hide

         cherrypy.session['last_date'] = None

      raise cherrypy.HTTPRedirect('/browse')

   add_daemon_filter.exposed = True

   def set_view(self, view_name):

      view_name = "view_" + view_name

      if hasattr(self, view_name):
         cherrypy.session['browse_view'] = view_name

      raise cherrypy.HTTPRedirect('/browse')

   set_view.exposed = True

   def index(self, date = None, date_fmt = None, highlight = None):

      cluster = self.cluster_master

      daemons_hide = cherrypy.session.get('daemons_hide', [])

      browse_view = cherrypy.session.get('browse_view', "view_Multilog")

      if date and date_fmt:
         # odd date format, convert it to our standard format
         raise cherrypy.HTTPRedirect('/browse?date=%s' % time.strftime("%Y%m%d%H%M%S", time.strptime(date, date_fmt)))

      if date:
         if not date_fmt:
            date_fmt = "%Y%m%d%H%M%S"
         cherrypy.session['first_date'] = time.strptime(date, date_fmt)
         cherrypy.session['last_date'] = None
      elif not cherrypy.session.get('first_date'):
         cherrypy.session['first_date'] = cluster.time_begin()

      if highlight:
         cherrypy.session['highlight'] = re.compile("^(.*)(%s)(.*)$" % highlight, re.IGNORECASE)
      else:
         cherrypy.session['highlight'] = None

      yield cherrypy.root.header()

      yield """
<div style="float: right; text-align: right">

<form action="/browse/set_view" method="post">
<span style="color: green; font-size: smaller">View template</span><br>
<select onchange="javascript:this.form.submit()" style="width: 120px" name="view_name">"""

      for view_name in [ "Multilog", "Linear" ]:
         if browse_view == "view_" + view_name:
            yield """<option selected>%s""" % ( view_name )
         else:
            yield """<option>%s""" % ( view_name )

      yield """</select></form>"""

      if len(daemons_hide) > 0:
         yield """<div style="padding-top: 10px; text-align: right; font-size: smaller">"""
         yield """<div style="color: green">Active filters:</div>"""
         for filtered_daemon in daemons_hide:
            yield """<div>%s <a href="/browse/del_daemon_filter?daemon_name=%s"><img style="width: 10px; height: 10px" src="/static/images/Crystal_Clear_action_edit_remove.png"></a></div>""" % (filtered_daemon, filtered_daemon)
         yield """</div"""

      yield """</div>"""

      yield """<table style="padding-bottom: 30px"><tr><td style="width: 30px"/><td>"""

      yield """<form method="post"><span style="color: green; font-size: smaller">Display logs starting at date</span><br><input name="date_fmt" type="hidden" value="%Y-%m-%d %H:%M:%S">"""

      yield """<input onchange="javascript:this.form.submit();" style="width: 120px" name="date" id="date" class="datechooser" dc-dateformat='Y-n-j 00:00:00' dc-iconlink='/static/3rd-party/datechooser/datechooser.png' dc-startdate='%s' dc-earliestdate='%s'" dc-latestdate='%s' type="text" value="%s">""" % ( time.strftime("%m%d%Y 00:00:00", cluster.time_begin()), time.strftime("%m%d%Y", cluster.time_begin()), time.strftime("%m%d%Y", cluster.time_end()), time.strftime("%Y-%m-%d %H:%M:%S", cherrypy.session.get('first_date')) )

      yield """</form>"""

      yield """<td><img src="/static/images/1px.gif" style="padding-left: 5px; padding-right: 5px; height: 50px; width: 1px"></td>"""

      yield """<td><form action="/browse/add_daemon_filter" method="post"><span style="color: green; font-size: smaller">Filter results</span><br><select onchange="javascript:this.form.submit()" style="color: #cacaca" name="daemon_name">"""

      yield """<option value="">Pick a daemon to filter out from results"""

      for (key, hits) in cluster.list_daemon_hits()[0:20]:
         if key in daemons_hide:
            continue
         yield """<option style="color: black" value="%s">%s (%d lines)""" % ( key, key, hits )

      yield """</select></form></td>"""

      yield """<td><img src="/static/images/1px.gif" style="padding-left: 5px; padding-right: 5px; height: 50px; width: 1px"></td>"""

      yield """<td><form action="/browse/set_max_rows" method="post"><span style="color: green; font-size: smaller">Rows per page</span><br><select onchange="javascript:this.form.submit()" name="max_rows">"""

      max_rows = cherrypy.session.get('max_rows', 500)

      for opts in [ 50, 100, 200, 500, 1000, 2000, 5000 ]:
         if opts == max_rows:
            yield """<option selected>%d""" % opts
         else:
            yield """<option>%d""" % opts

      yield """</select></form></td>"""

      yield """</tr></table>"""

      yield """<div><a href="/browse/back"><img alt="Previous" style="padding-right: 10px" src="/static/images/32px-Crystal_Clear_action_2leftarrow.png"></a> <a href="/browse/forward"><img alt="Next" src="/static/images/32px-Crystal_Clear_action_2rightarrow.png"></a></div>"""

      cluster_view = cluster_view_class(cluster, cherrypy.session.get('first_date', None), max_rows = max_rows, filter_daemons = cherrypy.session.get('daemons_hide', []) )

      yield getattr(self, browse_view)(cluster_view)

      yield """<div><a href="/browse/back"><img alt="Previous" style="padding-right: 10px" src="/static/images/32px-Crystal_Clear_action_2leftarrow.png"></a> <a href="/browse/forward"><img alt="Next" src="/static/images/32px-Crystal_Clear_action_2rightarrow.png"></a></div>"""

      yield cherrypy.root.footer()

   def view_Multilog(self, cluster_view):

      cluster = self.cluster_master

      hosts = cluster.host_names()

      yield """<table id="widget" class="grid" border="0" cellpadding="0" cellspacing="1">"""
      yield """<thead>"""
      yield """ <tr>"""
      yield """  <th style="width: 60px">Time</th>\n"""

      td_size = round(800 / len(hosts))

      for hostname in hosts:
         yield """  <th style="min-width: %dpx">%s</th>\n""" % (td_size, hostname)

      yield """ </tr>\n</thead>\n"""

      yield """<tbody id="logs">\n"""

      current_time = None
      td_pos = 0
      first_td_hostname = None
      tr_buffer = []
      tr_time_buffer = None
      prev_log = None

      for log in cluster_view.step_multiplex():

         if first_td_hostname and log.host.hostname() == first_td_hostname:
            sumlens = 0
            for inc in tr_buffer:
               sumlens+=len(inc)
            if sumlens == 0:
               tr_buffer = []
               tr_time_buffer = None

         if not first_td_hostname:
            first_td_hostname = log.host.hostname()

         elif log.host.hostname() == first_td_hostname and len(tr_buffer) > 0:

            if cluster_view.row % 2 == 0:
               tr_class = "odd"
            else:
               tr_class = "even"

            yield """ <tr class="%s">\n""" % tr_class
            yield """  <td>%s</td>\n""" % tr_time_buffer
            for td in tr_buffer:
               yield """  <td style="width: %dpx">%s</td>\n""" % (td_size, td)
            yield """ </tr>\n"""

            tr_buffer = []
            tr_time_buffer = None

         if log.empty():
            tr_buffer.append("")

         else:

            if not cherrypy.session.keys().count('first_date'):
               # save the first date
               cherrypy.session['first_date'] = log.date()

            # always save the last date
            cherrypy.session['last_date'] = log.date()

            if not prev_log or log.date()[0:3] != prev_log.date()[0:3]:
               # new date
               yield """ <tr class="newday">\n"""
               yield """  <td colspan=%d>%s</td>\n""" % (len(hosts)+1, time.strftime("%d %B %Y", log.date()))
               yield """ </tr>\n"""

            # this will be our first TD containing the timestamp
            if not tr_time_buffer:
               tr_time_buffer = """<a title="%s" href="/browse?date=%s#%s">%s</a>""" % (time.strftime("%d %B %Y %H:%M:%S", log.date()), log.timestamp(), log.id(), time.strftime("%H:%M:%S", log.date()))

            out = log.html_print()

            out = """<a name="%s">%s</a>\n""" % ( log.id(), out )

            tr_buffer.append(out)

            prev_log = log

      else:

         if len(tr_buffer):

            if cluster_view.row % 2 == 0:
               tr_class = "odd"
            else:
               tr_class = "even"

            yield """ <tr class="%s">\n""" % tr_class
            yield """  <td>%s</td>\n""" % tr_time_buffer
            for td in tr_buffer:
               yield """  <td style="width: %dpx">%s</td>\n""" % (td_size, td)
            yield """ </tr>\n"""

      yield """</tbody></table>"""

   def view_Linear(self, cluster_view):

      cluster = self.cluster_master

      colors = [ "#E6FFCC", "#CCE6FF", "#FFCCFF", "#99CCFF" ]

      yield """<table id="widget" class="grid" border="0" cellpadding="0" cellspacing="1">"""
      yield """<thead>"""
      yield """ <tr>"""
      yield """  <th>Time</th>\n"""
      yield """  <th>Host</th>\n"""
      yield """  <th></th>\n"""
      yield """ </tr>\n</thead>\n"""
      yield """<tbody id="logs">\n"""

      for log in cluster_view.step_multiplex(skip_empty = True):

         if cluster_view.count % 2 == 0:
            tr_class = "even"
         else:
            tr_class = "odd"

         yield """ <tr class="%s">\n""" % tr_class

         yield """  <td style="white-space: nowrap;"><a name="%s" href="%s">%s</a></td>\n""" % (log.id(), cherrypy.root.link_to_log(log), log.syslog_timestamp())

         yield """  <td><div style="text-align: center; border: 1px solid gray; padding: 1px; padding-left: 5px; padding-right: 5px; background-color: %s;">%s</div></td>\n""" % (colors[ cluster.hosts.keys().index(log.hostname()) % (len(colors) + 1) ], log.hostname())

         yield """  <td style="width: 100%%;">%s\n""" % log.html_print()

         yield """ </td></tr>\n"""

      yield """</tbody></table>\n"""

   def back(self, step_bytes_back = 1024 * 128):

      cluster = self.cluster_master

      start_date = cherrypy.session.get('first_date', cluster.time_begin())

      positions = cluster.get_position_by_date(start_date)

      for host, pos in positions.items():
         positions[host] = pos - step_bytes_back
         if positions[host] < 0:
            positions[host] = 0

      cherrypy.session['last_date'] = cherrypy.session.get('first_date', None)
      cherrypy.session['first_date'] = min( cluster.get_dates_at_position(positions).values() )

      raise cherrypy.HTTPRedirect('/browse')

   def forward(self):

      cluster = self.cluster_master

      cherrypy.session['first_date'] = cherrypy.session.get('last_date', cluster.time_begin())

      raise cherrypy.HTTPRedirect('/browse')

   index.exposed = True
   back.exposed = True
   forward.exposed = True
